#ifndef _sdl_options_h_
#define	_sdl_options_h_

#include <string>
#include <cstdlib>
#include "sdl_debug.h"
#include "sdl_prim.h"
#include "sdl_layer.h"
#include "sdl_engine.h"
#include "boost/program_options.hpp"
#include <iomanip>

#ifndef	sdl_env_prefix
#define sdl_env_prefix "NKFSDL_"
#endif

namespace po = boost::program_options;

class sdl_options : public sdl_singleton<sdl_options>, public sdl_prim,
depends<sdl_debug::debug> {
    po::variables_map variables;
public:

    sdl_options() : sdl_prim("options") {
    }

    void read_command_line(int argc, char ** argv, po::options_description desc) {
        try {
            po::store(po::parse_command_line(argc, argv, desc), variables);
            po::notify(variables);
        } catch (po::unknown_option & e) {
            _msg("options", 10, "nieznana opcja na linii poleceń: " << e.what());
        }
    }

    void read_environment(po::options_description desc) {
        try {
            po::store(po::parse_environment(desc, sdl_env_prefix), variables);
            po::notify(variables);
        } catch (po::unknown_option & e) {
            _msg("options", 10, "nieznana opcja w środowisku " << e.what());
        }
    }

    void read_config_file(std::istream & file, po::options_description desc) {
        try {
            po::store(po::parse_config_file(file, desc, true), variables);
            po::notify(variables);
        } catch (po::unknown_option & e) {
            _msg("options", 10, "nieznana opcja w strumieniu " << e.what());
        }
    }

    template<class data_t>
    data_t get(const std::string & opt) {
        if (variables.count(opt.c_str()))
            return variables[opt.c_str()].as<data_t > ();
        else return data_t();
    }

    int is_set(const std::string & opt) {
        return variables.count(opt.c_str());
    }
};

#endif 

